package com.anlogic.sdk.ui.tests.utils;

import java.util.Arrays;
import java.util.regex.Pattern;

import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot;
import org.eclipse.swtbot.eclipse.finder.waits.Conditions;
import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotView;
import org.eclipse.swtbot.swt.finder.SWTBot;
import org.eclipse.swtbot.swt.finder.waits.DefaultCondition;
import org.eclipse.swtbot.swt.finder.waits.ICondition;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotTree;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem;


public class SoftcoreUtils {
	public static void softcore(SWTWorkbenchBot bot,String projectName,String coreLight,String Optimization) {
		    bot.waitUntil(Conditions.shellIsActive("data - FutureDynasty"), 60 * 1000);

		    bot.waitUntil(new DefaultCondition() {
		        @Override
		        public boolean test() throws Exception {
		            return bot.menu("File").menu("New").menu("Project...").isEnabled();
		        }

		        @Override
		        public String getFailureMessage() {
		            return "Menu 'Project...' is not available or not enabled.";
		        }
		    }, 60 * 1000);

		    bot.menu("File").menu("New").menu("Project...").click();
		    bot.waitUntil(Conditions.shellIsActive("New Project"), 10 * 1000);

		    SWTBotTree tree = bot.tree();

		    // 等待 "C/C++" 项出现
		    bot.waitUntil(new TreeItemAvailable(tree, "C/C++"), 60 * 1000);
		    SWTBotTreeItem cppNode = tree.getTreeItem("C/C++");
		    cppNode.select();
		    cppNode.doubleClick();

		    // 等待 "C/C++ Project" 出现
		    bot.waitUntil(new TreeNodeAvailable(cppNode, "C/C++ Project"), 60 * 1000);
		    cppNode.getNode("C/C++ Project").select();
		    cppNode.getNode("C/C++ Project").doubleClick();

		    // 等待 "Executable > RISCV C Project (Softcore)" 出现

		    bot.table().select(0);
		    bot.button("Next >").click();
		    SWTBotTreeItem exeNode = bot.tree().getTreeItem("Executable");
		    bot.waitUntil(new TreeNodeAvailable(exeNode, "RISCV C Project (Softcore)"), 20 * 1000);
		    exeNode.getNode("RISCV C Project (Softcore)").select();

		    bot.textWithLabel("&Project name:").setText("softcore");

		    bot.button("Next >").click();
		    bot.comboBox(0).setSelection(projectName);
		    bot.comboBox(1).setSelection(coreLight);
		    bot.comboBox(2).setSelection(Optimization);
		    bot.button("Next >").click();
		    bot.button("Finish").click();

		    bot.viewByTitle("Project Explorer").show();
		    bot.waitUntil(new DefaultCondition() {
		        @Override
		        public boolean test() throws Exception {
		            return ((SWTWorkbenchBot) bot).viewByTitle("Project Explorer").bot().tree().getAllItems().length > 0;
		        }

		        @Override
		        public String getFailureMessage() {
		            return "Project tree did not load.";
		        }
		    }, 20 * 1000);

		    bot.viewByTitle("Project Explorer").bot().tree().select("softcore").contextMenu("Build Project").click();

		    SWTBotView consoleView = bot.viewByPartName("Console");
		    consoleView.setFocus();

		    if (consoleView.isActive()) {
		        System.out.println(111);
		        Pattern p = Pattern.compile(".*Build Finished. 0 errors.*", Pattern.DOTALL);
		        bot.waitUntil(consoleTextMatches(consoleView, p), 60 * 1000);
		    }
		}

		protected static ICondition consoleTextMatches(SWTBotView consoleView, Pattern pattern) {
		    return new ConsoleTextMatches(consoleView, pattern);
		}

		static class ConsoleTextMatches implements ICondition {
		    private final SWTBotView view;
		    private final Pattern pattern;

		    public ConsoleTextMatches(SWTBotView view, Pattern pattern) {
		        this.view = view;
		        this.pattern = pattern;
		    }

		    @Override
		    public boolean test() {
		        if (view.isActive()) {
		            String output = view.bot().styledText().getText();
		            return pattern.matcher(output).matches();
		        }
		        return false;
		    }

		    @Override
		    public void init(SWTBot bot) {}

		    @Override
		    public String getFailureMessage() {
		        return "Expected console text pattern not matched.";
		    }
		}

		static class TreeItemAvailable implements ICondition {
		    private final SWTBotTree tree;
		    private final String itemText;

		    public TreeItemAvailable(SWTBotTree tree, String itemText) {
		        this.tree = tree;
		        this.itemText = itemText;
		    }

		    @Override
		    public boolean test() {
		        return Arrays.stream(tree.getAllItems())
		                     .anyMatch(item -> item.getText().equals(itemText));
		    }

		    @Override
		    public void init(SWTBot bot) {}

		    @Override
		    public String getFailureMessage() {
		        return "Tree item '" + itemText + "' not available.";
		    }
		}

		static class TreeNodeAvailable implements ICondition {
		    private final SWTBotTreeItem parent;
		    private final String nodeText;

		    public TreeNodeAvailable(SWTBotTreeItem parent, String nodeText) {
		        this.parent = parent;
		        this.nodeText = nodeText;
		    }

		    @Override
		    public boolean test() {
		        try {
		            for (SWTBotTreeItem child : parent.getItems()) {
		                if (child.getText().equals(nodeText)) {
		                    return true;
		                }
		            }
		        } catch (Exception ignored) {}
		        return false;
		    }

		    @Override
		    public void init(SWTBot bot) {}

		    @Override
		    public String getFailureMessage() {
		        return "Tree node '" + nodeText + "' not available under '" + parent.getText() + "'.";
		    }
		}


}
